package com.xh.bussiness.permission.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.xh.bussiness.course.bean.dto.PrepareLessonsInfoDto;
import com.xh.bussiness.course.bean.dto.PrepareLessonsStatisticsDto;
import com.xh.bussiness.course.bean.dto.TeachResearchStatisticsDto;
import com.xh.bussiness.course.bean.request.StatisticsCompareDto;
import com.xh.bussiness.course.model.CourseIndex;
import com.xh.bussiness.course.service.ICourseIndexService;
import com.xh.bussiness.permission.service.IIndexStatisticsService;
import com.xh.bussiness.resource.model.Material;
import com.xh.bussiness.resource.service.IMaterialService;
import com.xh.bussiness.tiku.model.Paper;
import com.xh.bussiness.tiku.model.Question;
import com.xh.bussiness.tiku.service.IPaperService;
import com.xh.bussiness.tiku.service.IQuestionService;
import com.xh.core.util.CacheUtils;
import com.xh.core.util.DateUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import java.util.*;

@Service
public class IndexStatisticsServiceImpl implements IIndexStatisticsService {
    // 昨天自建题目数 缓存key的前缀
    public static final String USER_YESTERDAY_QUESTION_NUM_KEY_PREFIX = "USER_YESTERDAY_QUESTION_NUM_";
    // 昨天自建试卷数 缓存key的前缀
    public static final String USER_YESTERDAY_PAPER_NUM_KEY_PREFIX = "USER_YESTERDAY_PAPER_NUM_";
    // 昨天课件上传数 缓存key的前缀
    public static final String USER_YESTERDAY_COURSEWARE_NUM_KEY_PREFIX = "USER_YESTERDAY_COURSEWARE_NUM_";
    // 昨天讲义上传数 缓存key的前缀
    public static final String USER_YESTERDAY_HANDOUT_NUM_KEY_PREFIX = "USER_YESTERDAY_HANDOUT_NUM_";
    // 上周我的排名 缓存key的前缀
    public static final String USER_LAST_WEEK_RANK_KEY_PREFIX = "USER_LAST_WEEK_RANK_";
    // 上月我的排名 缓存key的前缀
    public static final String USER_LAST_MONTH_RANK_KEY_PREFIX = "USER_LAST_MONTH_RANK_";
    // 昨天备课数 缓存key的前缀
    public static final String USER_YESTERDAY_TIME_KEY_PREFIX = "USER_YESTERDAY_TIME_";
    // 上周备课数 缓存key的前缀
    public static final String USER_LAST_WEEK_TIME_KEY_PREFIX = "USER_LAST_WEEK_TIME_";
    // 上月备课数 缓存key的前缀
    public static final String USER_LAST_MONTH_TIME_KEY_PREFIX = "USER_LAST_MONTH_TIME_";

    @Autowired
    private IQuestionService questionService;
    @Autowired
    private IPaperService paperService;
    @Autowired
    private IMaterialService materialService;
    @Autowired
    private ICourseIndexService courseIndexService;

    // 教研统计
    @Override
    public TeachResearchStatisticsDto teachResearchStatistics(String userId) {
        // 今天开始
        Date beginOfDay = DateUtils.begin(new Date(), Calendar.DAY_OF_YEAR);

        // 今天自建题目数 和昨天对比
        StatisticsCompareDto questionNum = todayAndYesterdayQuestionNum(beginOfDay, userId);

        // 今天自建试卷数 和昨天对比
        StatisticsCompareDto paperNum = todayAndYesterdayPaperNum(beginOfDay, userId);

        // 今天课件上传数 和昨天对比
        StatisticsCompareDto coursewareNum = todayAndYesterdayCoursewareNum(beginOfDay, userId);

        // 今天讲义上传数 和昨天对比
        StatisticsCompareDto handoutNum = todayAndYesterdayHandoutNum(beginOfDay, userId);

        // 返回
        TeachResearchStatisticsDto result = new TeachResearchStatisticsDto();
        result.setQuestionNum(questionNum);
        result.setPaperNum(paperNum);
        result.setCoursewareNum(coursewareNum);
        result.setHandoutNum(handoutNum);
        return result;
    }

    // 今天自建题目数 和昨天对比
    private StatisticsCompareDto todayAndYesterdayQuestionNum(Date beginOfDay, String userId) {
        // 今天结束
        Date endOfDay = DateUtils.end(beginOfDay, Calendar.DAY_OF_YEAR);
        // 今天自建题目数
        int todayQuestionNum = questionNum(beginOfDay, endOfDay, userId);

        // 昨天自建题目数
        int yesterdayQuestionNum;
        String cacheKey = USER_YESTERDAY_QUESTION_NUM_KEY_PREFIX + userId + "_" + beginOfDay.getTime();
        Object o = CacheUtils.get(cacheKey);
        if(o != null) {
            yesterdayQuestionNum = Integer.parseInt(String.valueOf(o));
        } else {
            // 昨天开始yesterday
            Date beginOfYesterday = DateUtils.offset(beginOfDay, Calendar.DAY_OF_YEAR, -1);
            // 昨天结束
            Date endOfYesterday = DateUtils.end(beginOfYesterday, Calendar.DAY_OF_YEAR);
            // 昨天自建题目数
            yesterdayQuestionNum = questionNum(beginOfYesterday, endOfYesterday, userId);
            // 加缓存
            CacheUtils.set(cacheKey, yesterdayQuestionNum);
        }

        // 返回
        StatisticsCompareDto result = new StatisticsCompareDto();
        result.setCurrent(todayQuestionNum);
        result.setPrevious(yesterdayQuestionNum);
        return result;
    }

    // 自建题目数
    private int questionNum(Date beginQueryTime, Date endQueryTime, String userId) {
        QueryWrapper<Question> qw = new QueryWrapper<>();
        qw.eq("creator_id", userId);
//        qw.eq("status", 3);
        qw.ge("create_time", beginQueryTime);
        qw.le("create_time", endQueryTime);
        return questionService.selectCount(qw);
    }

    // 今天自建试卷数 和昨天对比
    private StatisticsCompareDto todayAndYesterdayPaperNum(Date beginOfDay, String userId) {
        // 今天结束
        Date endOfDay = DateUtils.end(beginOfDay, Calendar.DAY_OF_YEAR);
        // 今天自建试卷数
        int todayPaperNum = paperNum(beginOfDay, endOfDay, userId);

        // 昨天自建试卷数
        int yesterdayPaperNum;
        String cacheKey = USER_YESTERDAY_PAPER_NUM_KEY_PREFIX + userId + "_" + beginOfDay.getTime();
        Object o = CacheUtils.get(cacheKey);
        if(o != null) {
            yesterdayPaperNum = Integer.parseInt(String.valueOf(o));
        } else {
            // 昨天开始yesterday
            Date beginOfYesterday = DateUtils.offset(beginOfDay, Calendar.DAY_OF_YEAR, -1);
            // 昨天结束
            Date endOfYesterday = DateUtils.end(beginOfYesterday, Calendar.DAY_OF_YEAR);
            // 昨天自建试卷数
            yesterdayPaperNum = paperNum(beginOfYesterday, endOfYesterday, userId);
            // 加缓存
            CacheUtils.set(cacheKey, yesterdayPaperNum);
        }

        // 返回
        StatisticsCompareDto result = new StatisticsCompareDto();
        result.setCurrent(todayPaperNum);
        result.setPrevious(yesterdayPaperNum);
        return result;
    }

    // 自建试卷数
    private int paperNum(Date beginQueryTime, Date endQueryTime, String userId) {
        QueryWrapper<Paper> qw = new QueryWrapper<>();
        qw.eq("creator_id", userId);
//        qw.eq("check_status", 2);
        qw.ge("create_time", beginQueryTime);
        qw.le("create_time", endQueryTime);
        return paperService.selectCount(qw);
    }

    // 今天课件上传数 和昨天对比
    private StatisticsCompareDto todayAndYesterdayCoursewareNum(Date beginOfDay, String userId) {
        // 今天结束
        Date endOfDay = DateUtils.end(beginOfDay, Calendar.DAY_OF_YEAR);
        // 今天课件上传数
        int todayCoursewareNum = coursewareNum(beginOfDay, endOfDay, userId);

        // 昨天课件上传数
        int yesterdayCoursewareNum;
        String cacheKey = USER_YESTERDAY_COURSEWARE_NUM_KEY_PREFIX + userId + "_" + beginOfDay.getTime();
        Object o = CacheUtils.get(cacheKey);
        if(o != null) {
            yesterdayCoursewareNum = Integer.parseInt(String.valueOf(o));
        } else {
            // 昨天开始yesterday
            Date beginOfYesterday = DateUtils.offset(beginOfDay, Calendar.DAY_OF_YEAR, -1);
            // 昨天结束
            Date endOfYesterday = DateUtils.end(beginOfYesterday, Calendar.DAY_OF_YEAR);
            // 昨天课件上传数
            yesterdayCoursewareNum = coursewareNum(beginOfYesterday, endOfYesterday, userId);
            // 加缓存
            CacheUtils.set(cacheKey, yesterdayCoursewareNum);
        }

        // 返回
        StatisticsCompareDto result = new StatisticsCompareDto();
        result.setCurrent(todayCoursewareNum);
        result.setPrevious(yesterdayCoursewareNum);
        return result;
    }

    // 课件上传数
    private int coursewareNum(Date beginQueryTime, Date endQueryTime, String userId) {
        QueryWrapper<Material> qw = new QueryWrapper<>();
        qw.eq("creator_id", userId);
        // 课件
        qw.eq("type", 1);
        qw.ge("create_time", beginQueryTime);
        qw.le("create_time", endQueryTime);
        return materialService.selectCount(qw);
    }

    // 今天讲义上传数 和昨天对比
    private StatisticsCompareDto todayAndYesterdayHandoutNum(Date beginOfDay, String userId) {
        // 今天结束
        Date endOfDay = DateUtils.end(beginOfDay, Calendar.DAY_OF_YEAR);
        // 今天讲义上传数
        int todayHandoutNum = handoutNum(beginOfDay, endOfDay, userId);

        // 昨天讲义上传数
        int yesterdayHandoutNum;
        String cacheKey = USER_YESTERDAY_HANDOUT_NUM_KEY_PREFIX + userId + "_" + beginOfDay.getTime();
        Object o = CacheUtils.get(cacheKey);
        if(o != null) {
            yesterdayHandoutNum = Integer.parseInt(String.valueOf(o));
        } else {
            // 昨天开始yesterday
            Date beginOfYesterday = DateUtils.offset(beginOfDay, Calendar.DAY_OF_YEAR, -1);
            // 昨天结束
            Date endOfYesterday = DateUtils.end(beginOfYesterday, Calendar.DAY_OF_YEAR);
            // 昨天讲义上传数
            yesterdayHandoutNum = handoutNum(beginOfYesterday, endOfYesterday, userId);
            // 加缓存
            CacheUtils.set(cacheKey, yesterdayHandoutNum);
        }

        // 返回
        StatisticsCompareDto result = new StatisticsCompareDto();
        result.setCurrent(todayHandoutNum);
        result.setPrevious(yesterdayHandoutNum);
        return result;
    }

    // 讲义上传数
    private int handoutNum(Date beginQueryTime, Date endQueryTime, String userId) {
        QueryWrapper<Material> qw = new QueryWrapper<>();
        qw.eq("creator_id", userId);
        // 讲义
        qw.eq("type", 2);
        qw.ge("create_time", beginQueryTime);
        qw.le("create_time", endQueryTime);
        return materialService.selectCount(qw);
    }

    // 备课统计
    @Override
    public PrepareLessonsStatisticsDto prepareLessonsStatistics(String userId) {
        // 今天开始
        Date beginOfDay = DateUtils.begin(new Date(), Calendar.DAY_OF_YEAR);

        // 最近30天
        Date beginQueryTime = DateUtils.offset(beginOfDay, Calendar.DAY_OF_YEAR, -30);
        Date endQueryTime = DateUtils.end(beginOfDay, Calendar.DAY_OF_YEAR);

        // 备课排名 最近30天 前三名
        List<PrepareLessonsInfoDto> prepareLessonsRank = courseIndexService.prepareLessonsRank(beginQueryTime, endQueryTime, 3);





        // 我的排名 最近30天
        int myPrepareLessonsRank = courseIndexService.myPrepareLessonsRank(beginQueryTime, endQueryTime, userId);

        // 本周备课排名 和上周对比
        Map<String, Integer> thisWeekAndLastWeekRank = thisWeekAndLastWeekRank(beginOfDay, userId);
        int compareLastWeekRank = thisWeekAndLastWeekRank.get("compare");

        // 本月备课排名 和上月对比
        Map<String, Integer> thisMonthAndLastMonthRank = thisMonthAndLastMonthRank(beginOfDay, userId);
        int compareLastMonthRank = thisMonthAndLastMonthRank.get("compare");

        // 今天备课数 和昨天对比
        StatisticsCompareDto dayTime = todayAndYesterdayTime(beginOfDay, userId);

        // 本周备课数 和上周对比
        StatisticsCompareDto weekTime = thisWeekAndLastWeekTime(beginOfDay, userId);

        // 本月备课数 和上月对比
        StatisticsCompareDto monthTime = thisMonthAndLastMonthTime(beginOfDay, userId);

        // 返回
        PrepareLessonsStatisticsDto result = new PrepareLessonsStatisticsDto();
        result.setPrepareLessonsRank(prepareLessonsRank);
        result.setMyPrepareLessonsRank(myPrepareLessonsRank);
        result.setCompareLastWeekRank(compareLastWeekRank);
        result.setCompareLastMonthRank(compareLastMonthRank);
        result.setDayTime(dayTime);
        result.setWeekTime(weekTime);
        result.setMonthTime(monthTime);
        return result;
    }

    //  本周备课排名 和上周对比
    private Map<String, Integer> thisWeekAndLastWeekRank(Date beginOfDay, String userId) {
        // 本周第一天
        Date beginOfWeek = DateUtils.begin(beginOfDay, Calendar.WEEK_OF_YEAR);
        // 本周最后一天
        Date endOfWeek = DateUtils.end(beginOfWeek, Calendar.WEEK_OF_YEAR);
        // 本周我的排名
        int thisWeekRank = courseIndexService.myPrepareLessonsRank(beginOfWeek, endOfWeek, userId);

        // 上周我的排名
        int lastWeekRank;
        String cacheKey = USER_LAST_WEEK_RANK_KEY_PREFIX + userId + "_" + beginOfWeek.getTime();
        Object o = CacheUtils.get(cacheKey);
        if(o != null) {
            lastWeekRank = Integer.parseInt(String.valueOf(o));
        } else {
            // 上周第一天
            Date beginOfLastWeek = DateUtils.offset(beginOfWeek, Calendar.WEEK_OF_YEAR, -1);
            // 上周最后一天
            Date endOfLastWeek = DateUtils.end(beginOfLastWeek, Calendar.WEEK_OF_YEAR);
            // 上周我的排名
            lastWeekRank = courseIndexService.myPrepareLessonsRank(beginOfLastWeek, endOfLastWeek, userId);
            // 加缓存
            CacheUtils.set(cacheKey, lastWeekRank);
        }

        // 返回
        Map<String, Integer> result = new HashMap<>();
        result.put("thisWeekRank", thisWeekRank);
        result.put("lastWeekRank", lastWeekRank);
        result.put("compare", thisWeekRank - lastWeekRank);
        return result;
    }

    // 本月备课排名 和上月对比
    private Map<String, Integer> thisMonthAndLastMonthRank(Date beginOfDay, String userId) {
        // 本月第一天
        Date beginOfMonth = DateUtils.begin(beginOfDay, Calendar.MONTH);
        // 本月最后一天
        Date endOfMonth = DateUtils.end(beginOfMonth, Calendar.MONTH);
        // 本月我的排名
        int thisMonthRank = courseIndexService.myPrepareLessonsRank(beginOfMonth, endOfMonth, userId);

        // 上月我的排名
        int lastMonthRank;
        String cacheKey = USER_LAST_MONTH_RANK_KEY_PREFIX + userId + "_" + beginOfMonth.getTime();
        Object o = CacheUtils.get(cacheKey);
        if(o != null) {
            lastMonthRank = Integer.parseInt(String.valueOf(o));
        } else {
            // 上月第一天
            Date beginOfLastMonth = DateUtils.offset(beginOfMonth, Calendar.MONTH, -1);
            // 上月最后一天
            Date endOfLastMonth = DateUtils.end(beginOfLastMonth, Calendar.MONTH);
            // 上月我的排名
            lastMonthRank = courseIndexService.myPrepareLessonsRank(beginOfLastMonth, endOfLastMonth, userId);
            // 加缓存
            CacheUtils.set(cacheKey, lastMonthRank);
        }

        // 返回
        Map<String, Integer> result = new HashMap<>();
        result.put("thisMonthRank", thisMonthRank);
        result.put("lastMonthRank", lastMonthRank);
        result.put("compare", thisMonthRank - lastMonthRank);
        return result;
    }

    // 今天备课数 和昨天对比
    private StatisticsCompareDto todayAndYesterdayTime(Date beginOfDay, String userId) {
        // 今天结束
        Date endOfDay = DateUtils.end(beginOfDay, Calendar.DAY_OF_YEAR);
        // 今天备课数
        int todayTime = myPrepareLessonsTime(beginOfDay, endOfDay, userId);

        // 昨天备课数
        int yesterdayTime;
        String cacheKey = USER_YESTERDAY_TIME_KEY_PREFIX + userId + "_" + beginOfDay.getTime();
        Object o = CacheUtils.get(cacheKey);
        if(o != null) {
            yesterdayTime = Integer.parseInt(String.valueOf(o));
        } else {
            // 昨天开始yesterday
            Date beginOfYesterday = DateUtils.offset(beginOfDay, Calendar.DAY_OF_YEAR, -1);
            // 昨天结束
            Date endOfYesterday = DateUtils.end(beginOfYesterday, Calendar.DAY_OF_YEAR);
            // 昨天备课数
            yesterdayTime = myPrepareLessonsTime(beginOfYesterday, endOfYesterday, userId);
            // 加缓存
            CacheUtils.set(cacheKey, yesterdayTime);
        }

        // 返回
        StatisticsCompareDto result = new StatisticsCompareDto();
        result.setCurrent(todayTime);
        result.setPrevious(yesterdayTime);
        return result;
    }

    // 本周备课数 和上周对比
    private StatisticsCompareDto thisWeekAndLastWeekTime(Date beginOfDay, String userId) {
        // 本周第一天
        Date beginOfWeek = DateUtils.begin(beginOfDay, Calendar.WEEK_OF_YEAR);
        // 本周最后一天
        Date endOfWeek = DateUtils.end(beginOfWeek, Calendar.WEEK_OF_YEAR);
        // 本周备课数
        int thisWeekTime = myPrepareLessonsTime(beginOfWeek, endOfWeek, userId);

        // 上周备课数
        int lastWeekTime;
        String cacheKey = USER_LAST_WEEK_TIME_KEY_PREFIX + userId + "_" + beginOfWeek.getTime();
        Object o = CacheUtils.get(cacheKey);
        if(o != null) {
            lastWeekTime = Integer.parseInt(String.valueOf(o));
        } else {
            // 上周第一天
            Date beginOfLastWeek = DateUtils.offset(beginOfWeek, Calendar.WEEK_OF_YEAR, -1);
            // 上周最后一天
            Date endOfLastWeek = DateUtils.end(beginOfLastWeek, Calendar.WEEK_OF_YEAR);
            // 上周备课数
            lastWeekTime = myPrepareLessonsTime(beginOfLastWeek, endOfLastWeek, userId);
            // 加缓存
            CacheUtils.set(cacheKey, lastWeekTime);
        }

        // 返回
        StatisticsCompareDto result = new StatisticsCompareDto();
        result.setCurrent(thisWeekTime);
        result.setPrevious(lastWeekTime);
        return result;
    }

    // 本月备课数 和上月对比
    private StatisticsCompareDto thisMonthAndLastMonthTime(Date beginOfDay, String userId) {
        // 本月第一天
        Date beginOfMonth = DateUtils.begin(beginOfDay, Calendar.MONTH);
        // 本月最后一天
        Date endOfMonth = DateUtils.end(beginOfMonth, Calendar.MONTH);
        // 本月备课数
        int thisMonthTime = myPrepareLessonsTime(beginOfMonth, endOfMonth, userId);

        // 上月备课数
        int lastMonthTime;
        String cacheKey = USER_LAST_MONTH_TIME_KEY_PREFIX + userId + "_" + beginOfMonth.getTime();
        Object o = CacheUtils.get(cacheKey);
        if(o != null) {
            lastMonthTime = Integer.parseInt(String.valueOf(o));
        } else {
            // 上月第一天
            Date beginOfLastMonth = DateUtils.offset(beginOfMonth, Calendar.MONTH, -1);
            // 上月最后一天
            Date endOfLastMonth = DateUtils.end(beginOfLastMonth, Calendar.MONTH);
            // 上月备课数
            lastMonthTime = myPrepareLessonsTime(beginOfLastMonth, endOfLastMonth, userId);
            // 加缓存
            CacheUtils.set(cacheKey, lastMonthTime);
        }

        // 返回
        StatisticsCompareDto result = new StatisticsCompareDto();
        result.setCurrent(thisMonthTime);
        result.setPrevious(lastMonthTime);
        return result;
    }

    // 备课次数
    private int myPrepareLessonsTime(Date beginQueryTime, Date endQueryTime, String userId) {
        QueryWrapper<CourseIndex> qw = new QueryWrapper<>();
        qw.eq("creator_id", userId);
        // 备课
        qw.eq("lesson_status", 2);
        qw.ge("create_time", beginQueryTime);
        qw.le("create_time", endQueryTime);
        return courseIndexService.selectCount(qw);

    }
}
